#ifndef ROOT_NODE_H
#define ROOT_NODE_H

#include "matrix.h"

#include "stdio.h"
#include "stdlib.h"
#include <list>
#include <deque>
#include <vector>

#include "volAND.h"
#include "volOR.h"
#include "tanOR.h"
#include "tanAND.h"
#include "imgData.h"
#include "visualizer.h"

#include "AR/ar.h"

class rootNode{
public:
	rootNode(){};
	~rootNode(){};

	//bool initialRootNode(const char* mat_file_path, std::vector<int> node_index_list);
	bool initialRootNode(const char* path, std::vector<int> node_index_list, const char* weight_file_name);
	bool inference(const char* file_name);
	bool inferenceV2(const char* file_name);
	bool sequentialDetection(const char* file_name);
	bool detection(const char* file_name);
	bool inferenceSW(const char* file_name, bool use_color);
	bool cropHardNegExample(const char *file_name,std::deque<rootParticle_s> &hard_negative );
	bool randomCollectNegExample(const char *file_name,int num_particle,std::deque<rootParticle_s> &negative );


	bool release();
	bool updateParticleList(rootParticle_s & particle);
	void test(float P[3][4],float cam_dir[3],	rootParticle_s &particle);
	void argMax(rootParticle_s &particle,const char* template_name=NULL);

	void raiseViewPoint(float pan, float tilt, float roll, float dist, view_s &view);
	//void SWTest(view_s view, rootParticle_s &root_particle);
	float *SWTest(view_s view, bool use_color);
	/* crop bounding box for each possible hypothesis*/
	void cropHypothesisBB(float *score_map, const view_s &view, float threshold, int num);
	/* non-max supression*/
	void nonMaxSuppression(float threshold, int num, float max_overlap);


	bool loadImageToModel(const char*file_name);
	bool clearImageInModel(){return image.release();};
	/*functions for LR reweight*/
	int countFeatureDimension();
	bool alignFeature(rootParticle_s &root_particle,float *p_feature_vec);

	bool coarseSearch(std::deque<rootParticle_s> &hard_negative);
	void lookAround(float srcP[3][4], rootParticle_s &particle);

	void lookAroundV2(float srcP[3][4], rootParticle_s &particle);

private:
	void saveHypoList(const char* mat_file_list);
	bool readHypoList(const char* mat_file_list);
	bool insertVolORNode(const char* vol_path, int tree_id, FILE *p_weight_file);
	bool insertVolANDNode(const mxArray *p_tree, const char* vol_path, int i_tree, int vol_id, FILE *p_weight_file);
	bool insertTanORNode(const mxArray *p_layer,int i_node, int i_layer, const char* tree_path,FILE *p_weight_file);

	std::deque<volOR>  vol_OR_list;
	std::deque<volAND> vol_AND_list;
	std::deque<tanOR>  tan_OR_list;
	std::deque<tanAND> tan_AND_list;




	std::vector<int> f_table_tan;
	std::vector<int> f_table_feature;
	bool refitP(float pan,float tilt, float roll, float dist, int dx, int dy, int sx, int sy, view_s &view);
	void estimateBB(view_s &view);
	imgData image;

	visualizer window;
	std::list<rootParticle_s> root_particle_list;

	//memory on 3D and 2D data points
	float X[28][4];
	float x[28][3];


	struct BB_s{
		int top; int bottom;
		int left; int right;
		float pose[4]; /*pan,tilt,roll,dist*/
		int position;/*point at which the detection is performed*/
		rootParticle_s *p_particle;
		float score;
		bool operator<( BB_s &that){
			/*this leads to descent sort*/
			return this->score > that.score;
		}
	};
	float BBOverlap(std::list<BB_s>::iterator itr1,std::list<BB_s>::iterator itr2);

	std::list<BB_s> hypoBBList;
};












#endif

